package org.fuxia.im.core.service.impl;

import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.fuxia.im.core.ECMessageType;
import org.fuxia.im.core.entries.ECPacket;
import org.fuxia.im.core.entries.ECResponse;
import org.fuxia.im.core.entries.ECSession;
import org.fuxia.im.core.iconst.Constant;
import org.fuxia.im.core.iconst.ServerConst;
import org.fuxia.im.core.server.ECSessionMananger;
import org.fuxia.im.core.server.ServerSideContext;
import org.fuxia.im.core.utils.ObjectUtil;
import org.fuxia.im.db.dao.ChatGroupDaoImpl;
import org.fuxia.im.db.dao.UserDaoImpl;
import org.fuxia.im.db.dao.UserFriendDaoImpl;
import org.fuxia.im.db.dao.UserGroupDaoImpl;
import org.fuxia.im.entities.ChatGroup;
import org.fuxia.im.entities.User;
import org.fuxia.im.entities.UserGroup;
/**
 * 处理用户登陆请求
 *
 */
public class ServiceLogin extends AbstractService
{
	private static final Logger	logger	= Logger.getLogger(ServiceLogin.class);

	@Resource
	private UserDaoImpl			userDao;
	@Resource
	private UserGroupDaoImpl	userGroupDaoImpl;
	@Resource
	private UserFriendDaoImpl	userFriendDaoImpl;
	@Resource
	private ChatGroupDaoImpl chatGroupDao ;

	public void service(ECPacket packet)
	{
		switch (ECMessageType.valueOf(packet.getMessageType()))
		{
		case LOGIN:
			serviceLogin(packet);
			break;
		case LOGOUT:
			serviceLogout(packet);
			break;
		}
	}

	private void serviceLogout(ECPacket packet)
	{
		ECSession session = ECSessionMananger.getInstance().getUserSession(packet.getFrom());
		if(session==null) {
			String sessionId = packet.getParameter(ServerConst.SESSION_ID.name());
			session = ECSessionMananger.getInstance().removeTempedSession(sessionId);
		}
		if(session!=null) {
			SocketChannel client = session.getChannel();
			Selector sel = (Selector) ServerSideContext.getContext().get(ServerConst.SERVER_SELECTOR);
			SelectionKey key = client.keyFor(sel);
			try
			{
				key.cancel();
			}
			catch (Exception e)
			{
				logger.error("客户端注销失败", e);
			}
		}
		ECSessionMananger.getInstance().removeUserSession(packet.getFrom()) ;
		logger.info("{" + session.getConnectedUser() + "}注销成功");
		logger.info("当前在线人数：" + ECSessionMananger.getInstance().getOnlineUserCount()+ "（人）") ;
	}

	@SuppressWarnings("unchecked")
	private void serviceLogin(ECPacket packet)
	{
		String userCode = packet.getParameter(Constant.USERCODE.name());
		
		if(ECSessionMananger.getInstance().hasLogin(userCode)) {
			
			ECResponse resp = new ECResponse();
			resp.setResponseType("LOGIN_RESP");
			resp.put("loginResult", "用户已经登录");
			resp.setStatusCode(400);
			packet.setFrom(null);
			writeReponse(packet, resp);
			return ;
		}
		
		
		String password = packet.getParameter(Constant.PASSWORD.name());
		
		String sessionId = packet.getParameter(ServerConst.SESSION_ID.name());
		ECSession session = ECSessionMananger.getInstance().getSession(sessionId);
		
		ECResponse resp = new ECResponse();
		resp.setResponseType("LOGIN_RESP");
		
		User user = userDao.getByPK(userCode);
		if (user != null && password.equals(user.getPassword()) && !user.getIsDiable())
		{
			session.setConnectedUser(userCode);
			ECSessionMananger.getInstance().reisterValidSession(userCode, session);
			ECSessionMananger.getInstance().removeSession(sessionId);

			String selGroupHql = "select ug from UserGroup ug where ug.userCode=:userCode";
			List<UserGroup> groups = userGroupDaoImpl
					.findByNamedParam(selGroupHql, new String[] { "userCode" }, new String[] { userCode });

			Map<String, List<Object>> userFriends = new HashMap<String, List<Object>>();
			for (UserGroup ug : groups)
			{
				//某用户的某好友组中有哪些好友
				String selFriends = "select user.userCode,uf.nickName,user.personNote,user.userState,"
						+ "user.imagePath,user.age,user.address,user.sex "
						+ "from IMUser user,UserFriend uf where "
						+ "user.userCode=uf.friendUserCode and uf.orignUserCode=:orignUserCode and uf.groupId=:groupId";
				List<Object> result = userFriendDaoImpl.findByNamedParam(
						selFriends,
						new String[] { "orignUserCode",
						"groupId" }, new String[] { userCode, ug.getId() });
					List<Object> friends = new ArrayList<Object>();
					for (int i = 0; i < result.size(); i++)
					{
						friends.add(result.get(i));
					}
					userFriends.put(ug.getId() + "#" + ug.getGroupName(), friends);
			}
			List<ChatGroup> chatGroups = null ;
			try{
				chatGroups = chatGroupDao.findChatGroups(userCode) ;
			}catch (Exception e) {
			}
			
			user.setPassword("") ;
			resp.put("user", ObjectUtil.getJsonStr(user));
			resp.put("friends", ObjectUtil.getJsonStr(userFriends));
			resp.put("chatGroups", ObjectUtil.getJsonStr(chatGroups));
			resp.setStatusCode(200);
		}
		else
		{
			resp.put("loginResult", "登录失败");
			resp.setStatusCode(400);
		}
		try
		{
			writeReponse(packet, resp) ;
		}
		catch (Exception e)
		{
			logger.error("向客户端发送信息失败", e);
		}
	}
}
